import datetime
from django.apps import apps
from loguru import logger
from apps.website.models import CodeManage


def set_delete(queryset, model=None):
    """
    批量设置is_del=True
    """
    if not queryset:
        return

    for ob in queryset:
        ob.is_delete = True
    if model:
        model.objects.bulk_update(queryset, ["is_delete"])
    else:
        queryset.bulk_update(queryset, ["is_delete"])


def handle_time(hour):
    if hour > 12:
        return hour - 12
    return hour

def get_model(app_name, model_name):
    """
    通过模块名和model名获取model对象
    :param app_name:
    :param model_name:
    :return:
    """
    try:
        model = apps.get_model(app_name, model_name)
    except Exception as e:
        raise Exception(e)

    return model
def flow_code_manage(value, user: int = None, dept: int = None, now_time=None):
    """
    同handle_code_manage方法，区别：上述方法走序列化器，当走流程时则走这个方法返回一个编码
    """

    code_manage = CodeManage.objects.filter(anchor_point=value)
    if code_manage.count() == 0:
        raise Exception("未找到需要设置的编码类型!")

    cm = code_manage.first()

    rule = cm.rule

    now_time = datetime.datetime.now() if not now_time else now_time
    logger.debug("rule is %s" % rule)
    rule = (
        rule.replace(" ", "")
        .replace("{year}", str(now_time.year))
        .replace("{month}", str(now_time.month).zfill(2))
        .replace("{day}", str(now_time.day).zfill(2))
        .replace("{h12}", str(handle_time(now_time.hour)).zfill(2))
        .replace("{h24}", str(now_time.hour).zfill(2))
        .replace("{min}", str(now_time.minute).zfill(2))
        .replace("{sec}", str(now_time.second).zfill(2))
    )
    logger.debug("trans rule is %s" % rule)
    logger.debug(code_manage.first().app)
    logger.debug(code_manage.first().model)
    model = get_model(app_name=code_manage.first().app, model_name=code_manage.first().model)

    queryset = model.objects
    if hasattr(model, "is_delete"):
        queryset = queryset.filter(is_delete=False)
    logger.debug({cm.field + "__startswith": rule})
    queryset = queryset.filter(**{cm.field + "__startswith": rule})

    if queryset.count == 0:
        ret_code = f"{rule}{str(1).zfill(cm.sequence_len)}"
    else:
        # 考虑截取的自定义序列 是否在数据库有同等长度的， 因为强制转化为int， 可能会缩短
        # 有，max + 1, 没有  1
        sequences = [code.split(rule)[-1] for code in queryset.values_list(cm.field, flat=True)]
        seq_len = [len(sl) for sl in sequences]
        if cm.sequence_len in seq_len:
            max_s = 0
            for seq in sequences:
                if len(seq) == cm.sequence_len and int(seq) > max_s:
                    max_s = int(seq)
            ret_code = f"{rule}{str(max_s + 1).zfill(cm.sequence_len)}"
        else:
            ret_code = f"{rule}{str(1).zfill(cm.sequence_len)}"

    return ret_code

def check_serial_num(serial_num, model, check_field_name="serial_num"):
    """
    校验生成流水号是否重复
    @param check_field_name:
    @param serial_num:
    @param model:
    @return:
    """
    filter_dic = {check_field_name: serial_num}
    if hasattr(model, "is_delete"):
        filter_dic["is_delete"] = False
    assert not model.objects.filter(**filter_dic), "数据库中已存在该流水号！"

    return serial_num


def create_by_serializer(serializer, data, **kwargs):
    """
    通过序列化方式创建
    @param serializer:
    @param data:
    @return:
    """
    if not serializer or not data:
        return

    kwargs["data"] = data
    kwargs["many"] = True if isinstance(data, list) else False
    serializer = serializer(**kwargs)
    serializer.is_valid(raise_exception=True)
    serializer.save()

    return serializer

